<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="com.puppycrawl.tools.checkstyle.Checker">

	<!-- Suppressions -->
	<module name="SuppressionFilter">
		<property name="file" value="${config_loc}/checkstyle-suppressions.xml"/>
	</module>

	<!-- Root Checks -->
	<module name="io.spring.javaformat.checkstyle.check.SpringHeaderCheck">
		<property name="fileExtensions" value="java"/>
		<property name="headerType" value="apache2"/>
		<property name="headerCopyrightPattern" value="20\d\d-20\d\d"/>
		<property name="packageInfoHeaderType" value="none"/>
	</module>
	<module name="com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck"/>
	<module name="JavadocPackage" /><!-- package-info.java -->

	<!-- TreeWalker Checks -->
	<module name="com.puppycrawl.tools.checkstyle.TreeWalker">

		<!-- Package-level null-safety annotations -->
		<module name="RegexpSinglelineJavaCheck">
			<property name="id" value="packageLevelNonNullApiAnnotation"/>
			<property name="format" value="@NonNullApi"/>
			<property name="minimum" value="1"/>
			<property name="maximum" value="1"/>
			<property name="message" value="package-info.java is missing required null-safety annotation @NonNullApi."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module name="RegexpSinglelineJavaCheck">
			<property name="id" value="packageLevelNonNullFieldsAnnotation"/>
			<property name="format" value="@NonNullFields"/>
			<property name="minimum" value="1"/>
			<property name="maximum" value="1"/>
			<property name="message" value="package-info.java is missing required null-safety annotation @NonNullFields."/>
			<property name="ignoreComments" value="true"/>
		</module>

		<!-- Annotations -->
		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck">
			<property name="elementStyle" value="compact"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.MissingOverrideCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.PackageAnnotationCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationLocationCheck">
			<property name="allowSamelineSingleParameterlessAnnotation" value="false"/>
		</module>

		<!-- Block Checks -->
		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.EmptyBlockCheck">
			<property name="option" value="text"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck">
			<property name="option" value="alone"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.NeedBracesCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.AvoidNestedBlocksCheck"/>

		<!-- Class Design -->
		<module name="com.puppycrawl.tools.checkstyle.checks.design.FinalClassCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.design.InterfaceIsTypeCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.design.MutableExceptionCheck">
			<property name="format" value="^.*Exception$"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.design.InnerTypeLastCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.design.OneTopLevelClassCheck"/>

		<!-- Type Names -->
		<module name="TypeName">
			<property name="format" value="^[A-Z][a-zA-Z0-9_$]*(?&lt;!Test)$"/>
			<property name="tokens" value="CLASS_DEF"/>
			<message key="name.invalidPattern"
				value="Class name ''{0}'' must not end with ''Test'' (checked pattern ''{1}'')."/>
		</module>

		<!-- Coding -->
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.CovariantEqualsCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.EmptyStatementCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.EqualsHashCodeCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanExpressionCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanReturnCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.StringLiteralEqualityCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedForDepthCheck">
			<property name="max" value="3"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedIfDepthCheck">
			<property name="max" value="5"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedTryDepthCheck">
			<property name="max" value="3"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheck"/>

		<module name="io.spring.javaformat.checkstyle.filter.RequiresOuterThisFilter"/>
		<module name="io.spring.javaformat.checkstyle.filter.IdentCheckFilter">
			<property name="names" value="logger"/>
			<module name="com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck">
				<property name="checkMethods" value="false"/>
				<property name="validateOnlyOverlapping" value="false"/>
			</module>
		</module>
		<module name="io.spring.javaformat.checkstyle.check.SpringNoThisCheck">
			<property name="names" value="logger"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck"/>

		<!-- Imports -->
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.RedundantImportCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.UnusedImportsCheck">
			<property name="processJavadoc" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck">
			<property name="groups" value="java,javax,*,org.springframework"/>
			<property name="ordered" value="true"/>
			<property name="separated" value="true"/>
			<property name="option" value="bottom"/>
			<property name="sortStaticImportsAlphabetically" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
			<property name="id" value="bannedImports"/>
			<property name="regexp" value="true"/>
			<property name="illegalClasses"
				value="^reactor\.core\.support\.Assert,^org\.slf4j\.LoggerFactory,^(?!org\.springframework).*(NonNull|Nonnull|NonNullApi|NonNullFields|Nullable)$"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
			<property name="id" value="bannedJUnit3Imports"/>
			<property name="regexp" value="true"/>
			<property name="illegalClasses" value="^junit\.framework\..+"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
			<property name="id" value="bannedJUnit4Imports"/>
			<property name="regexp" value="true"/>
			<property name="illegalClasses"
				value="^org\.junit\.(Test|BeforeClass|AfterClass|Before|After|Ignore|FixMethodOrder|Rule|ClassRule|Assert|Assume)$,^org\.junit\.(Assert|Assume)\..+,^org\.junit\.(experimental|internal|matchers|rules|runner|runners|validator)\..+"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
			<property name="id" value="bannedJUnitJupiterImports"/>
			<property name="regexp" value="true"/>
			<property name="illegalClasses" value="^org\.junit\.jupiter\..+"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
			<property name="id" value="bannedTestNGImports"/>
			<property name="regexp" value="true"/>
			<property name="illegalClasses" value="^org\.testng\..+,"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
			<property name="id" value="bannedHamcrestImports"/>
			<property name="regexp" value="true"/>
			<property name="illegalClasses" value="^org\.hamcrest\..+"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
			<property name="id" value="bannedJetbrainsAnnotationsImports"/>
			<property name="regexp" value="true"/>
			<property name="illegalClasses" value="^org\.jetbrains\.annotations\..+"/>
		</module>

		<!-- Javadoc Comments -->
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck">
			<property name="scope" value="package"/>
			<property name="authorFormat" value=".+\s.+"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck">
			<property name="allowMissingParamTags" value="true"/>
			<property name="allowMissingReturnTag" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck">
			<property name="scope" value="public"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheck">
			<property name="checkEmptyJavadoc" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.NonEmptyAtclauseDescriptionCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagContinuationIndentationCheck">
			<property name="offset" value="0"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck">
			<property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF"/>
			<property name="tagOrder" value="@author, @since, @param, @see, @version, @serial, @deprecated"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck">
			<property name="target" value="METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
			<property name="tagOrder" value="@param, @return, @throws, @since, @see, @deprecated"/>
		</module>

		<!-- Modifiers -->
		<module name="com.puppycrawl.tools.checkstyle.checks.modifier.ModifierOrderCheck"/>

		<!-- Whitespace -->
		<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.SingleSpaceSeparatorCheck"/>

		<!-- Miscellaneous -->
		<module name="com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck">
			<property name="tokens" value="BLOCK_COMMENT_BEGIN"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.UpperEllCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.ArrayTypeStyleCheck"/>
		<module name="com.puppycrawl.tools.checkstyle.checks.OuterTypeFilenameCheck"/>
		<module name="UnnecessarySemicolonInEnumeration"/>

		<!-- Regexp -->
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="format" value="^\t* +\t*\S"/>
			<property name="message"
				value="Line has leading space characters; indentation should be performed with tabs only."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpCheck">
			<property name="format" value="[ \t]+$"/>
			<property name="illegalPattern" value="true"/>
			<property name="message" value="Trailing whitespace"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="id" value="atSinceVersionConvention"/>
			<property name="format" value="\@since \d+\.\d+\.0"/>
			<property name="maximum" value="0"/>
			<property name="message"
					  value="@since should use Major.Minor version convention instead of Major.Minor.0"/>
			<property name="ignoreComments" value="false"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="id" value="primitiveClassLiterals"/>
			<property name="maximum" value="0"/>
			<property name="format" value="(Boolean|Character|Byte|Short|Integer|Long|Float|Double|Void)\.TYPE"/>
			<property name="message" value="Please use class literals for primitives and void -- for example, int.class instead of Integer.TYPE."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module
			name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="maximum" value="0"/>
			<property name="format"
				value="assertThatExceptionOfType\((NullPointerException|IllegalArgumentException|IOException|IllegalStateException)\.class\)"/>
			<property name="message"
				value="Please use specialized AssertJ assertThat*Exception method."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="id" value="bddMockito"/>
			<property name="maximum" value="0"/>
			<property name="format" value="org\.mockito\.Mockito\.(when|doThrow|doAnswer)"/>
			<property name="message" value="Please use BDDMockito."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="id" value="expectedExceptionAnnotation"/>
			<property name="maximum" value="0"/>
			<property name="format" value="\@Test\(expected"/>
			<property name="message" value="Please use AssertJ assertions."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="id" value="junit4Assertions"/>
			<property name="maximum" value="0"/>
			<property name="format" value="org\.junit\.Assert"/>
			<property name="message" value="Please use AssertJ assertions."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="id" value="junitJupiterAssertions"/>
			<property name="maximum" value="0"/>
			<property name="format" value="org\.junit\.jupiter\.api\.Assertions"/>
			<property name="message" value="Please use AssertJ assertions."/>
			<property name="ignoreComments" value="true"/>
		</module>
		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
			<property name="id" value="testNGAssertions"/>
			<property name="maximum" value="0"/>
			<!-- should cover org.testng.Assert and org.testng.AssertJUnit -->
			<property name="format" value="org\.testng\.Assert(JUnit)?"/>
			<property name="message" value="Please use AssertJ assertions."/>
			<property name="ignoreComments" value="true"/>
		</module>

		<!-- Spring Conventions -->
		<module name="io.spring.javaformat.checkstyle.check.SpringLambdaCheck">
			<property name="singleArgumentParentheses" value="false"/>
		</module>
		<module name="io.spring.javaformat.checkstyle.check.SpringCatchCheck"/>
		<module name="io.spring.javaformat.checkstyle.check.SpringJavadocCheck"/>
		<module name="io.spring.javaformat.checkstyle.check.SpringJUnit5Check"/>

	</module>

</module>
